using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Practices.RepositoryFactory.SchemaDiscovery.ObjectModel.Base;
using Microsoft.Practices.RepositoryFactory.CodeGeneration.ObjectModel;
using Microsoft.Practices.RepositoryFactory.CodeGeneration.ObjectModel.Mappings;
using Microsoft.Practices.RepositoryFactory.CodeGeneration.ObjectModel.Mappings.Enums;
using System.Configuration;
using Microsoft.Practices.RepositoryFactory.CustomPages.Helpers;
using System.Data;
using Microsoft.Practices.RepositoryFactory.SchemaDiscovery;

namespace Microsoft.Practices.RepositoryFactory.CustomPages.CreateRepositoryPages
{
   public class CreateOperationViewPresenter : Presenter<ICreateOperationView>
   {
      private Entity entity;
      private EntityStoredProcedureMapping mapping;
      private OperationType operationType;
      private ConnectionStringSettings connectionSettings;

      public void OnViewLoad()
      {
         View.DisplayEntityName(entity.Name);

         List<StoredProcedure> storedProcedures = UIHelper.GetStoredProcedures(connectionSettings);
         View.FillStoredProcedures(storedProcedures);

         if (!string.IsNullOrEmpty(mapping.OperationName))
         {
            View.FillWithExistingData(mapping);
         }

         View.SetOperationType(operationType);
      }

      public bool IsOperationNameValid(string operationName)
      {
         if (string.IsNullOrEmpty(operationName))
            return false;

         if (string.Compare(mapping.OperationName, operationName, true) != 0)
         {
            foreach (EntityStoredProcedureMapping needle in entity.StoredProcedureMappings)
            {
               if (string.Compare(needle.OperationName, operationName, true) == 0)
               {
                  return false;
               }
            }
         }
         return true;
      }

      public CreateOperationViewPresenter(Entity entity, EntityStoredProcedureMapping mapping,
          ConnectionStringSettings connectionSettings)
      {
         this.entity = entity;
         this.mapping = mapping;
         this.operationType = mapping.OperationType;
         this.connectionSettings = connectionSettings;
      }

      public CreateOperationViewPresenter(Entity entity, EntityStoredProcedureMapping mapping,
          ConnectionStringSettings connectionSettings, bool editMode)
         : this(entity, mapping, connectionSettings)
      {

      }

      public void OnComplete(string operationName, StoredProcedure procedure)
      {
         mapping.OperationName = operationName;
         mapping.Procedure = procedure.Name;
         StoredProcedure procedureWithParameters = UIHelper.GetStoredProcedure(procedure.Name, connectionSettings);

         mapping.ProcedureHasInputParameters =
             procedureWithParameters.Parameters.Exists(delegate(Parameter parameter)
         {
            return (parameter.Direction == ParameterDirection.Input ||
                    parameter.Direction == ParameterDirection.InputOutput);
         });

         if (OperationType.DeleteOne == this.operationType)
         {
            CreateIdentity(procedureWithParameters);
         }
      }

      private void CreateIdentity(StoredProcedure procedure)
      {
         Identity identity = new Identity();
         identity.Name = mapping.OperationName + "Identity";

         List<Parameter> inputParameters =
             UIHelper.GetParameters(connectionSettings, procedure, ParameterDirection.Input);
         inputParameters.AddRange(
             UIHelper.GetParameters(connectionSettings, procedure, ParameterDirection.InputOutput));

         foreach (Parameter identityParameter in inputParameters)
         {
            identity.ParameterMappings.Add(new PropertyParameterMapping(identityParameter.Name,
                                                                        UIHelper.CloneParameter(identityParameter)));
         }

         mapping.Identity = identity;
      }

      public void OnProcedureChanged(StoredProcedure storedProcedure)
      {
         if (string.Compare(storedProcedure.Name, mapping.Procedure, StringComparison.InvariantCultureIgnoreCase) != 0)
         {
            mapping.ParameterMappings.Clear();
            View.DisplayOperationName(storedProcedure.Name);
         }
      }
   }
}
